using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.FEZ;
using System.IO;
using System.Text;
using System.Threading;

namespace AstroX
{
    public delegate void FlightPhaseChangeHandler(FlightPhases newphase);

    public class FlightControl
    {
        public const int FlightTime = 30*60;
        public const int ShutDownTime = 60;
        static string LockFile = "";

        static InterruptPort LaunchPin;
        static InterruptPort ExtendPin;
        static InterruptPort RetractPin;
        public static void Init(string rootpath)
        {

            Program.Print("Initializing Flight Controller");
            LaunchPin = new InterruptPort(AstoXPinMap.LaunchPin, true, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeBoth);
            ExtendPin = new InterruptPort(AstoXPinMap.ExtendPin, true, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeBoth);
            RetractPin = new InterruptPort(AstoXPinMap.RetractPin, true, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeBoth);

            LaunchPin.OnInterrupt += new NativeEventHandler(LaunchPin_OnInterrupt);
            ExtendPin.OnInterrupt += new NativeEventHandler(ExtendPin_OnInterrupt);
            RetractPin.OnInterrupt += new NativeEventHandler(RetractPin_OnInterrupt);
            LockFile = Path.Combine(rootpath, "lock.txt");

            if (LaunchPin.Read() || ExtendPin.Read() || RetractPin.Read())
            {
                Debug.Print("Invalid start state!");
                //Lock();  Think about this line alot!!
            }
        }

        
        static void RetractPin_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            Program.Print("Retract Line is " + data2.ToString());
            if (data2 != 1) { return; }
            if (CheckLocks()) { return; }
            
            Timer t = new Timer((o) =>
            {
                if (RetractPin.Read())
                {
                    CurrentPhase = FlightPhases.Retract;
                }
            }, null, 1000, 0);


        }

        public static void Lock()
        {
            Program.Print("Locking out changes");
            File.WriteAllBytes(LockFile, Encoding.UTF8.GetBytes(DateTime.Now.Second.ToString()));
        }

        private static bool CheckLocks()
        {
            if (File.Exists(LockFile))
            {
                return true;
            }
            return false;
        }

        static void ExtendPin_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            Program.Print("Extend Line is " + data2.ToString());
            if (data2 != 1) { return; }
            if (CheckLocks()) { return; }
            if (CurrentPhase != FlightPhases.Ascent) { return; }
            Timer t = new Timer((o) =>
            {
                if (ExtendPin.Read())
                {
                    CurrentPhase = FlightPhases.Extend;
                }
            }, null, 1000, 0);


            
            
        }

        static void LaunchPin_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            Program.Print("Launch Line is " + data2.ToString());
            if (data2 != 1) { return; }
            if (CheckLocks()) { return; }

            if (CurrentPhase != FlightPhases.StandingBy) { return; }


            Timer t = new Timer((o) =>
            {
                if (LaunchPin.Read())
                {
                    CurrentPhase = FlightPhases.Ascent;
                }
            }, null, 1000, 0);

        }


        public static event FlightPhaseChangeHandler FlightPhaseChanged;

        private static FlightPhases _currentPhase;

        public static FlightPhases CurrentPhase
        {
            get { return _currentPhase; }
            set
            {
                FlightPhases _oldphase = _currentPhase;
                _currentPhase = value;
                if (_currentPhase != _oldphase)
                {
                    OnPhaseChanged();
                }

            }
        }


        public static void OnPhaseChanged()
        {
            Program.Print(CurrentPhase.ToString());
            if (FlightPhaseChanged != null)
            {
                FlightPhaseChanged(CurrentPhase);
            }

        }



        public static int Seconds { get; set; }
    }

    public enum FlightPhases
    {
        Initializing = 0,
        StandingBy = 1,
        Ascent = 2,
        Extend = 3,
        Extending = 4,
        Extended = 5,
        Retract = 6,
        Retracting = 7,
        Retracted = 8,
        Descent = 9,
        Shutdown = 10,
    }
}
